package com.wj.facedetect.util;

import android.support.annotation.IdRes;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by tangkun on 2017/10/13.
 */

public class FragmentController {
    private static final String TAG = "FragmentController";
    private FragmentManager fragmentManager;
    private int containerViewId;
    private Fragment curVisibleFragment;
    private boolean allowingStateLoss;


    public FragmentController(@Nullable FragmentManager fragmentManager, @IdRes int containerViewId) {
        this.fragmentManager = fragmentManager;
        this.containerViewId = containerViewId;
    }

    public void setAllowingStateLoss(boolean allowingStateLoss) {
        this.allowingStateLoss = allowingStateLoss;
    }

    public void switchFragment(@Nullable Fragment fragment, @Nullable String tag) {
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        if (fragmentManager.findFragmentByTag(tag) != null) {
            if (curVisibleFragment == null) {
                transaction.show(fragment);
                commitTransaction(transaction);
                curVisibleFragment = fragment;
            } else if (curVisibleFragment != fragment) {
                transaction.hide(curVisibleFragment);
                transaction.show(fragment);
                commitTransaction(transaction);
                curVisibleFragment = fragment;
            }
        } else {
            if (curVisibleFragment != null) {
                transaction.hide(curVisibleFragment);
            }
            transaction.add(containerViewId, fragment, tag);
            transaction.show(fragment);
            commitTransaction(transaction);
            curVisibleFragment = fragment;
        }
    }

    public void removeFragment(@Nullable Fragment fragment) {
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.remove(fragment);
        commitTransaction(transaction);
    }

    public void removeAllFragment() {
        FragmentTransaction transcation = fragmentManager.beginTransaction();
        for (Fragment fragment : getAllFragment()) {
            transcation.remove(fragment);
        }
        setAllowingStateLoss(true);
        commitTransaction(transcation);
    }


    public Fragment getCurVisibleFragment() {
        return curVisibleFragment;
    }

    public void setCurVisibleFragment(Fragment curVisibleFragment) {
        this.curVisibleFragment = curVisibleFragment;
    }

    public FragmentManager getFragmentManager() {
        return fragmentManager;
    }

    public void setFragmentManager(FragmentManager fragmentManager) {
        this.fragmentManager = fragmentManager;
    }

    @SuppressWarnings("RestrictedApi")
    private List<Fragment> getAllFragment() {
        List<Fragment> fragments = fragmentManager.getFragments();
        if (fragments == null || fragments.isEmpty())
            return Collections.emptyList();
        List<Fragment> result = new ArrayList<>();
        for (Fragment fragment : fragments) {
            if (fragment != null) {
                result.add(fragment);
            }
        }
        return result;
    }

    public void hintCurVisbileFragment() {
        if (curVisibleFragment != null) {
            FragmentTransaction transaction = fragmentManager.beginTransaction();
            transaction.hide(curVisibleFragment);
            commitTransaction(transaction);
            curVisibleFragment = null;
        }
    }

    private void commitTransaction(FragmentTransaction transaction) {
        if (allowingStateLoss) {
            transaction.commitAllowingStateLoss();
            allowingStateLoss = false;
        } else {
            transaction.commit();
        }
    }

    private Timer timer;

    @SuppressWarnings("RestrictedApi")
    private void logFragmentList() {
        if (timer == null) {
            timer = new Timer();
        }
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                try {
                    StringBuilder sb = new StringBuilder();
                    sb.append("[");
                    boolean needDel = false;
                    for (Fragment fragment : fragmentManager.getFragments()) {
                        sb.append(fragment == null ? "null, " : fragment.toString() + ", ");
                        needDel = true;
                    }
                    if (needDel) {
                        sb.delete(sb.length() - 2, sb.length());
                    }
                    sb.append("]");
                    Log.e(TAG, sb.toString());
                } catch (NullPointerException e) {
                    e.printStackTrace();
                }
            }
        }, 1000);
    }
}
